
compono.ui.Balloon = compono.Class({
	timer:0.5,
	position:"auto",
	
	top:0,
	left:0,
	width:0,
	height:0,
	
	title:false,
	content:false,
	className:false,
	
	enabled:true,
	
	elements:false,
	currentElement:false,
	
	QUADRANT_CLASS_NAME:"balloon-{0}-{1}",
	
	html:false,
	
	TIMER_ID:false,
	run:function(element){

		if(element)
		{
			this.html = this.$(element);
			this.$T(this.html).forEach(function(node)
			{
				compono.DOMBuilder.prototype.createPath(node);
			},this)
		}
		else
		{
			var container = this.$D();
			container.DIV({"class":"balloon"},
				container.DIV({"class":"arrow"}),
				container.DIV({"class":"body"},
					container.H2({"class":"head"},"Title"),
					container.P({"class":"content"},"Content")
				)
			);
			this.html = this.$(container.render());
		};
		
		this.html.$balloon = this;
		
		this.html.event("mouseover",function(event)
		{
			this.$balloon.afterTimeout.timeout(false);
			this.$balloon.TIMER_ID = false;
		});
		
		this.html.event("mouseout",function(event)
		{
			this.$balloon.hide(event);
		})
		
		this.html.appendClassName(this.className);
		
		return this;
	},
	show:function(object,event){
		var update, enabled;
		if(!this.enabled){
			return;
		};
		if(this.TIMER_ID)
		{
			this.afterTimeout.timeout(false);
			this.TIMER_ID = false;
		};
		if(object)
		{
			if(object.nodeType)
			{
				enabled = object.attr("balloon-enabled");
			}
			else if(object.element)
			{
				enabled = object.element.attr("balloon-enabled");
			}
			else
			{
				return;
			};
			update = enabled ? enabled.toString().toLowerCase()=="false" : false;
		};
		if(!update)
		{
			if(this.onShow && this.onShow(object,event)==false)
			{
				return false;
			};
			this.setContent(object);
			this.html.appendClassName("balloon-visible");
			this.setPosition(object,event);
			if(this.position != "auto")
			{
				if(object.top){		this.html.css("top",object.top)};
				if(object.left){	this.html.css("left",object.left)};
				if(object.width){	this.html.css("width",object.width)};
				if(object.height){	this.html.css("height",object.height)};
			};
			this.currentElement = object.element;
			//setting ability to put a time to close;
			if(object.timer){
				this.hide(object, event);
			};
		};
		return this
	},	
	setContent:function(node){
		var title = 	node.element.attr("balloon-title") || 	node.element.proto.title || 	node.title || 		this.title;
		var content = 	node.element.attr("balloon-content") || node.element.proto.content || 	node.content || 	this.content;
		var css = 		node.element.attr("balloon-class") || 	node.element.proto.className || node.className || 	this.className;

		if(title)
		{
			this.$(this.html.body.head).html(this.core.Wiki.render(title))
		}
		else
		{
			this.$(this.html.body.head).hide();
		};
		
		if(content)
		{
			this.$(this.html.body.content).html(this.core.Wiki.render(content))
		}
		else
		{
			this.$(this.html.body.content).hide();
		};
		
		if(css)
		{
			this.$(this.html.body).appendClassName(css,1);
		};
		
		return this
	},
	setPosition:function(object, event){
		var top, left, csst="top", cssl="right";
		var body = this.$B().document;
		var scope = this.html;
		var cords = object.element.cords();
		
		top = cords.atop - this.html.offsetHeight;
		
		left = cords.aleft;
		
		if((top - body.scrollTop) < 0)
		{
			csst = "bottom";
			top = cords.atop + cords.height;
			
			if((top - body.scrollTop) < 0)
			{
				top = body.scrollTop;
			}
		};
		
		if((left + this.html.offsetWidth) > body.offsetWidth)
		{
			cssl = "left";
			left = cords.aleft - this.html.offsetWidth;
		};
		
		if(this.quadrant)
		{
			this.html.removeClassName(this.quadrant);
		};
		
		this.quadrant = this.QUADRANT_CLASS_NAME.format((this.position=="auto"?{0:csst,1:cssl}:this.position.split(" ")));
		
		this.html.appendClassName(this.quadrant);
		
		this.html.style.top = top + "px";
		this.html.style.left = left + "px";
		
		return this;
	},
	hide:function(object, event){
		if(!this.enabled){
			return;
		};
		if(this.onHide&&this.onHide(object, event)==false){
			return false;
		};
		
		var time = this.timer;
		//ability to close with custom time;
		if(object && object.timer){
			time = object.timer;
		};
		
		this.TIMER_ID = this.afterTimeout.timeout(time, this);
		return this;
	},
	afterTimeout:function(){
		this.html.removeClassName("balloon-visible");
		this.TIMER_ID = false;
	},
	attach:function(node,proto){
		if(node instanceof Array||(node.length && typeof(node)!="string"))
		{
			return node.forEach(function(item)
					{
						this.attach(item.element, item)
					},this);
		};
		var node = this.$(node);
		if(node&&!node.$balloon)
		{
			if(this.onAttach && this.onAttach(node)==false)
			{
				return false;
			};
			node.proto = proto || {};
			node.$balloon = this;
			node.balloonShow = function(object,event)
			{
				var force = (object.force == false || object.force) ? object.force : true;
				if(!object.hasOwnProperty('element')){
					object.element = this;
				};
				this.$balloon[ force ? 'show' : 'hide' ].call(this.$balloon, object, event);
			};
			
			node.event("mouseover",function(event)
			{
				this.$balloon.show({element:this},event);
			});
			
			node.event("mouseout",function(event)
			{
				this.$balloon.hide({element:this},event);
			});
			
			if(!this.elements)
			{
				this.elements = [];
			};
			this.elements.push(node);
		};
		return this
	}
})